package cn.demoncat.util.lang.entity.report;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Map;

import cn.demoncat.util.lang.NumberUtil;
import cn.demoncat.util.lang.ParamEmptyUtil;
import cn.demoncat.util.mybatis.constant.MapperConstant;
import cn.demoncat.util.lang.constant.ReportConstant;

/**
 * 报表参数 - 分时图表
 * 
 * @author 延晓磊
 *
 * @since 2019年12月11日
 */
public class ReportParamChartTime extends ReportTime {

	// 图表模式：ReportConstant.ModeTime
	private String mode;

	// 分组最大数，截止上个时间数
	private int maxValue;
	// 分组字段
	private String groupColumns;
	// 分组排序字段
	private String sortColumns;

	/**
	 * 获取图表参数 - 单维度
	 * 
	 * @param mode			模式：ReportConstant.ModeTime
	 * @param date			基准日期，用于查询历史日期的图表，默认当天（时表）、当月（日表）、当年（月表）
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static ReportParamChartTime build(String mode, ReportTime date) {
		return build(mode, date, false, false);
	}
	
	/**
	 * 获取图表参数 - 多维度
	 * 
	 * @param mode			模式：ReportConstant.ModeTime
	 * @param date			基准日期，用于查询历史日期的图表，默认当天（时表）、当月（日表）、当年（月表）
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static ReportParamChartTime buildMulit(String mode, ReportTime date) {
		return build(mode, date, true, false);
	}
	
	/**
	 * 获取图表参数 - 单/多维度
	 * 
	 * @param mode			模式：ReportConstant.ModeTime
	 * @param date			基准日期，用于查询历史日期的图表，默认当天（时表）、当月（日表）、当年（月表）
	 * @param countItem		是否多维统计Item项：多维度为true
	 * @param countTitle	是否多维统计Item项，并展示Title：用于多维度并且根据数据动态获取Legend的情况，这种数据Title须与Item保持一致不能变动
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	public static ReportParamChartTime build(String mode, ReportTime date, boolean countItem, boolean countTitle) {
		// 参数校验
		ParamEmptyUtil.checkBlank(mode);
		// 模式
		LocalDateTime now = LocalDateTime.now();
		ReportParamChartTime param = new ReportParamChartTime();
		param.setMode(mode);
		switch (mode) {
		case ReportConstant.ModeTime.HOUR:
			// 时表：可以限定查询的年、月、日，默认当天
			if (date == null) {
				param.setYear(now.getYear());
				param.setMonth(now.getMonthValue());
				param.setDay(now.getDayOfMonth());
			}else {
				param.setYear(NumberUtil.isBlank(date.getYear()) ? now.getYear() : date.getYear());
				param.setMonth(NumberUtil.isBlank(date.getMonth()) ? now.getMonthValue() : date.getMonth());
				param.setDay(NumberUtil.isBlank(date.getDay()) ? now.getDayOfMonth() : date.getDay());
			}
			// 最大时间，-1表示没有数据
			if (date == null || (now.getYear() == param.getYear() && now.getMonthValue() == param.getMonth() && now.getDayOfMonth() == param.getDay())) {
				// 当天，截止当前小时
				param.setMaxValue(now.getHour());
			}else {
				if (LocalDate.of(param.getYear(), param.getMonth(), param.getDay()).isAfter(now.toLocalDate())) {
					// 明天以后，无数据
					param.setMaxValue(-1);
				}else {
					// 昨天以前，满数据
					param.setMaxValue(23);
				}
			}
			// 分组字段
			if (countItem) {
				if (countTitle) {
					param.setColumns(ReportConstant.Column.HOUR_ITEM_TITLE);
				}else {
					param.setColumns(ReportConstant.Column.HOUR_ITEM);
				}
			}else {
				param.setColumns(ReportConstant.Column.HOUR);
			}
			return param;
		case ReportConstant.ModeTime.DAY:
			// 日表：可以限定查询的年、月、时，默认当月
			if (date == null) {
				param.setYear(now.getYear());
				param.setMonth(now.getMonthValue());
			}else {
				param.setYear(NumberUtil.isBlank(date.getYear()) ? now.getYear() : date.getYear());
				param.setMonth(NumberUtil.isBlank(date.getMonth()) ? now.getMonthValue() : date.getMonth());
				param.setHour(NumberUtil.isBlank(date.getHour()) ? null : date.getHour());
			}
			// 最大时间，-1表示没有数据
			if (date == null || (now.getYear() == param.getYear() && now.getMonthValue() == param.getMonth())) {
				// 当月，截止今天
				param.setMaxValue(now.getDayOfMonth());
			}else {
				if (LocalDate.of(param.getYear(), param.getMonth(), 1).isAfter(now.toLocalDate().withDayOfMonth(1))) {
					// 下月以后，无数据
					param.setMaxValue(-1);
				}else {
					// 上月以前，满数据
					param.setMaxValue(31);
				}
			}
			// 分组字段
			if (countItem) {
				if (countTitle) {
					param.setColumns(ReportConstant.Column.DAY_ITEM_TITLE);
				}else {
					param.setColumns(ReportConstant.Column.DAY_ITEM);
				}
			}else {
				param.setColumns(ReportConstant.Column.DAY);
			}
			return param;
		case ReportConstant.ModeTime.MONTH:
			// 月表：可以限定查询的年、日、时，默认当年
			if (date == null) {
				param.setYear(now.getYear());
			}else {
				param.setYear(NumberUtil.isBlank(date.getYear()) ? now.getYear() : date.getYear());
				param.setDay(NumberUtil.isBlank(date.getDay()) ? null : date.getDay());
				param.setHour(NumberUtil.isBlank(date.getHour()) ? null : date.getHour());
			}
			// 最大时间，-1表示没有数据
			if (date == null || (now.getYear() == param.getYear())) {
				// 当月，截止本月
				param.setMaxValue(now.getMonthValue());
			}else {
				if (param.getYear() < now.getYear()) {
					// 明年以后，无数据
					param.setMaxValue(-1);
				}else {
					// 去年以前，满数据
					param.setMaxValue(12);
				}
			}
			// 分组字段
			if (countItem) {
				if (countTitle) {
					param.setColumns(ReportConstant.Column.MONTH_ITEM_TITLE);
				}else {
					param.setColumns(ReportConstant.Column.MONTH_ITEM);
				}
			}else {
				param.setColumns(ReportConstant.Column.MONTH);
			}
			return param;
		case ReportConstant.ModeTime.YEAR:
			// 年表：可以限定查询的月、日、时，默认全部
			if (date != null) {
				param.setMonth(NumberUtil.isBlank(date.getMonth()) ? now.getMonthValue() : date.getMonth());
				param.setDay(NumberUtil.isBlank(date.getDay()) ? null : date.getDay());
				param.setHour(NumberUtil.isBlank(date.getHour()) ? null : date.getHour());
			}
			// 最大时间，无限制
			param.setMaxValue(100);
			
			// 分组字段
			if (countItem) {
				if (countTitle) {
					param.setColumns(ReportConstant.Column.YEAR_ITEM_TITLE);
				}else {
					param.setColumns(ReportConstant.Column.YEAR_ITEM);
				}
			}else {
				param.setColumns(ReportConstant.Column.YEAR);
			}
			return param;
		default:
			throw ReportConstant.CHART_MODE_ERROR;
		}
	}
	
	/**
	 * 整合分时图表查询参数
	 * 
	 * @param condition	查询参数：type,item,...
	 * 
	 * @return {查询参数，year, month, day, hour, groupColumns, sortColumns}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	@Override
	public Map<String, Object> getParams(Map<String, Object> condition){
		condition = super.getParams(condition);
		condition.put(MapperConstant.ParamName.GROUP_COLUMNS, this.getGroupColumns());
		condition.put(MapperConstant.ParamName.SORT_COLUMNS, this.getSortColumns());
		return condition;
	}
	
	/**
	 * 设置分组字段
	 * 
	 * @param column
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月11日
	 */
	private void setColumns(ReportConstant.Column column) {
		this.groupColumns = column.getGroupColumns();
		this.sortColumns = column.getSortColumns();
	}
	
	public String getMode() {
		return mode;
	}

	public void setMode(String mode) {
		this.mode = mode;
	}

	public int getMaxValue() {
		return maxValue;
	}

	public void setMaxValue(int maxValue) {
		this.maxValue = maxValue;
	}

	public String getGroupColumns() {
		return groupColumns;
	}

	public void setGroupColumns(String groupColumns) {
		this.groupColumns = groupColumns;
	}

	public String getSortColumns() {
		return sortColumns;
	}

	public void setSortColumns(String sortColumns) {
		this.sortColumns = sortColumns;
	}

}
